﻿/*
 * tcplistener.cpp
 *
 *  Created on: 2017年2月17日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_OS_COM DM_API_EXPORT

#include <dm/os/com/tcplistener.hpp>
#include <dm/os/log/logger.hpp>

namespace dm{
namespace os{
namespace com{

static const char* logModule = "CTcpListener.com.os.dm";

CTcpListener::CTcpListener( ios_t& ios ):CListener(),m_ios(&ios),m_acceptor(ios){
	log().debug(THISMODULE "创建对象");
}

CTcpListener::~CTcpListener(){
	log().debug(THISMODULE "销毁对象");
	if( m_acceptor.is_open() )
		m_acceptor.close();
	if( m_connect!=NULL )
		delete m_connect;
}

bool CTcpListener::checkAndSetAddress( const CTcpServerAddr& addr ){
	m_addr = addr;
	return true;
}

void CTcpListener::setConnectOnConnect( device_t* connect ){
	if( connect==0 ){
		log().warnning(THISMODULE "新连接不可以为空");
		return;
	}

	CTcpConnectedDevice* con = dynamic_cast<CTcpConnectedDevice*>(connect);

	CTcpConnectAddr addr;
	addr.setPeerHost(m_peer.address().to_string().c_str());
	addr.setPeerPort(m_peer.port());
	log().info(THISMODULE "收到新连接:%s:%u",addr.getPeerHost().c_str(),addr.getPeerPort());

	con->m_addr = addr;
	con->setConnected();
}

bool CTcpListener::openPort(){
	const CTcpServerAddr* addr = m_addr.asTcpServer();
	if( !addr ){
		log().error(THISMODULE "没有有效的地址");
		return false;
	}

	try{
		m_acceptor.open(boost::asio::ip::tcp::v4());
		m_acceptor.set_option( boost::asio::ip::tcp::acceptor::reuse_address(true));
		m_acceptor.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(addr->getLocalHost()),addr->getLocalPort()));
		m_acceptor.listen();
	}catch( std::exception& ec ){
		log().error(THISMODULE "打开设备%s监听失败(%s)",m_addr.toString().c_str(),ec.what());
		return false;
	}

	return true;
}

bool CTcpListener::closePort(){
	m_acceptor.close();
	return true;
}

CTcpListener::device_t* CTcpListener::startAccept( const size_t& bufSize ){
	log().debug(THISMODULE "申请一个新的设备");
	CTcpConnectedDevice* con = new CTcpConnectedDevice(*m_ios,bufSize);

	try{
		m_acceptor.async_accept(con->m_dev,m_peer,
				boost::bind(&CTcpListener::handler_connection,this,boost::asio::placeholders::error));
		return con;
	}catch( std::exception& e ){
		log().error(THISMODULE "异步接受连接失败 %s",e.what() );
		delete con;
		return 0;
	}
}

}
}
}
